﻿Imports System.Net.Sockets
''' <summary>
''' Holds either a Server or A Client Class for a Game in Order to recieve Data or Send it.
''' </summary>
''' <remarks></remarks>
Public Class LobbyConnection
    Dim Client As ClientClassLobby
    Dim Server As ServerClassLobby
    ''' <summary>
    ''' Starts a new Connection
    ''' </summary>
    ''' <param name="Hosten"></param>
    ''' <param name="IP"></param>
    ''' <remarks></remarks>
    Public Sub IniConnection(ByVal Hosten As Boolean, Optional ByVal IP As System.Net.IPAddress = Nothing)
        If Hosten Then
            Server = New ServerClassLobby()
            Server.LaunchServer(Hauptmenue.LobbyPort)
        Else
            If IP Is Nothing Then
                Client = New ClientClassLobby
                Client.Connect(Hauptmenue.LobbyPort)
            Else
                Client = New ClientClassLobby
                Client.Connect(DataSettings.LobbyServerIP, IP, Hauptmenue.LobbyPort)
            End If
        End If
    End Sub
    ''' <summary>
    ''' Send Data to other Player
    ''' </summary>
    ''' <param name="Data"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal Data As String)
        If Server IsNot Nothing Then
            Server.SendData(Data)
        ElseIf Client IsNot Nothing Then
            Client.SendData(Data)
        End If
    End Sub
    ''' <summary>
    ''' Send Data to other Player
    ''' </summary>
    ''' <param name="Data"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal Data As String, ByVal PlayerID As Integer)
        If Server IsNot Nothing Then
            Server.SendData(Data, PlayerID)
        End If
    End Sub
    ''' <summary>
    ''' Send Data to other Player
    ''' </summary>
    ''' <param name="Bytes"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal Bytes() As Byte, ByVal PlayerID As Integer)
        If Server IsNot Nothing Then
            Server.SendData(Bytes, PlayerID)
        End If
    End Sub
    ''' <summary>
    ''' Send Data to other Player
    ''' </summary>
    ''' <param name="Bytes"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal Bytes As Byte())
        If Server IsNot Nothing Then
            Server.SendData(Bytes)
        ElseIf Client IsNot Nothing Then
            Client.SendData(Bytes)
        End If
    End Sub
    ''' <summary>
    ''' Are we connected with somebody?
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Connected() As Boolean
        If Server IsNot Nothing Then
            Return Server.NetzConnected
        ElseIf Client IsNot Nothing Then
            Return Client.NetzConnected
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Are we the Host this Game?
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Hosten() As Boolean
        If Server IsNot Nothing Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' We won't to close this connection
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Close()
        Dim Hosten As Boolean = Hosten
        If Server IsNot Nothing Then
            Server.Close()
        End If
        If Client IsNot Nothing Then
            Client.Close()
        End If
    End Sub
    ''' <summary>
    ''' Updates this Connection
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Update()
        If Server IsNot Nothing Then
            'Send Server Pakets
            Server.SendPakets()
        End If
    End Sub
    Public Function GetServer() As ServerClassLobby
        Return Server
    End Function
End Class

''' <summary>
''' This Class manages the Client Side of a Game.
''' </summary>
''' <remarks></remarks>
''' 
Public Class ClientClassLobby
    ''' <summary>
    ''' Client Listener
    ''' </summary>
    ''' <remarks></remarks>
    Dim tcpClient As System.Net.Sockets.TcpClient
    ''' <summary>
    ''' Listening Thread
    ''' </summary>
    ''' <remarks></remarks>
    Dim ListenThread As Threading.Thread
    ''' <summary>
    ''' Closing connection
    ''' </summary>
    ''' <remarks></remarks>
    Dim CloseConnection As Boolean = False
    ''' <summary>
    ''' Backbuffer for our read in.
    ''' </summary>
    ''' <remarks></remarks>
    Dim Data As New List(Of Byte)
    ''' <summary>
    ''' The Current Position of our Reader.
    ''' </summary>
    ''' <remarks></remarks>
    Dim CurrentPos As Integer
    ''' <summary>
    ''' Did we have a connection
    ''' </summary>
    ''' <remarks></remarks>
    Dim HasConnected As Boolean = False
    ''' <summary>
    ''' You need to enter the new IP.
    ''' </summary>
    ''' <remarks></remarks>
    Public Function Connect(ByVal Port As Integer) As Boolean
        If MessageBox.ShowEnterIP = MsgBoxResult.Yes Then
            Dim IP As System.Net.IPAddress = Nothing
            If System.Net.IPAddress.TryParse(MessageBox.Output(0), IP) Then
                If Connect(MessageBox.Output(0), IP, Port) Then Return True
            Else
                Try
                    Dim IPEnter As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry(MessageBox.Output(0))
                    For I = 0 To IPEnter.AddressList.Length - 1
                        If IPEnter.AddressList(I).IsIPv6LinkLocal = False Then
                            If IPEnter.AddressList(I).IsIPv6Multicast = False Then
                                If IPEnter.AddressList(I).IsIPv6SiteLocal = False Then
                                    IP = IPEnter.AddressList(I)
                                    Connect(MessageBox.Output(0), IP, Port)
                                    Return True
                                    Exit For
                                End If
                            End If
                        End If
                        If I = IPEnter.AddressList.Length - 1 Then
                            Konsole.Write("Host IP not found.")
                            Close()
                        End If
                    Next
                Catch
                    Konsole.Write("Host IP not found.")
                    Close()
                End Try
            End If
        End If
        Return False
    End Function
    ''' <summary>
    ''' Connects with the IP and the Input Port.
    ''' </summary>
    ''' <param name="IP"></param>
    ''' <param name="Port"></param>
    ''' <remarks></remarks>
    Public Function Connect(ByVal IPStr As String, ByVal IP As System.Net.IPAddress, ByVal Port As Integer) As Boolean
        If IP Is Nothing And IPStr = "" Then
            Return Connect(Port)
        Else
            If IPStr <> "" Then
                Try
                    tcpClient = New System.Net.Sockets.TcpClient()
                    tcpClient.Connect(IPStr, Port)
                    tcpClient.ReceiveBufferSize = NetworkPaket.MaxRecieveBuffer

                    ListenThread = New Threading.Thread(AddressOf RecieveData)
                    ListenThread.Name = "Client Game Listening"
                    ListenThread.Start()
                    Return True
                Catch ex As Exception
                    Konsole.Write("Host Error! " + ex.Message)
                End Try
            End If
            Try
                tcpClient = New System.Net.Sockets.TcpClient(IP.AddressFamily) 'Create New Client
                tcpClient.Connect(IP, Port)
                tcpClient.ReceiveBufferSize = NetworkPaket.MaxRecieveBuffer
                ListenThread = New Threading.Thread(AddressOf RecieveData)
                ListenThread.Name = "Client Game Listening"
                ListenThread.Start()
                Return True
            Catch
                Try
                    If IP.AddressFamily = AddressFamily.InterNetworkV6 Then
                        IP = ConvertToNetworkIP(IP)
                    Else
                        IP = ConvertToInternetIP(IP)
                    End If
                    tcpClient = New System.Net.Sockets.TcpClient(IP.AddressFamily) 'Create New Client
                    tcpClient.Connect(IP, Port)
                    tcpClient.ReceiveBufferSize = NetworkPaket.MaxRecieveBuffer
                    ListenThread = New Threading.Thread(AddressOf RecieveData)
                    ListenThread.Name = "Client Game Listening"
                    ListenThread.Start()
                    Return True
                Catch ex As Exception
                    Konsole.Write("Host not found! " + ex.Message)
                End Try
            End Try
        End If
        Return False
    End Function
    ''' <summary>
    ''' Closes this Client Session.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Close()
        CloseConnection = True
        If ListenThread IsNot Nothing Then
            ListenThread.Abort()
        End If
        If tcpClient IsNot Nothing Then
            SendData(Net_Orders.Close_Connection.ToString)
            tcpClient.Close()
        End If
       
    End Sub
    ''' <summary>
    ''' Send Data to Host
    ''' </summary>
    ''' <param name="Data"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal Data As String)
        If tcpClient IsNot Nothing Then
            If NetzConnected() Then
                Data = NetworkPaket.GenerateStringStream(Data)
                Dim sendBytes As [Byte]() = Hauptmenue.Codierung.GetBytes(Data) 'Convert String into Bytes
                Try
                    Dim networkStream As NetworkStream = tcpClient.GetStream()
                    If networkStream.CanWrite Then
                        Dim DataSended As Boolean = False
                        While Not DataSended And NetzConnected()
                            networkStream.Write(sendBytes, 0, sendBytes.Length) 'Sending Data
                            DataSended = True
                        End While
                    End If
                Catch e As Exception
                    Konsole.Write("Sending Error: " + e.ToString)
                End Try
            End If
        End If
    End Sub
    ''' <summary>
    ''' Send Data to Host
    ''' </summary>
    ''' <param name="sendBytes"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal sendBytes As Byte())
        If tcpClient IsNot Nothing Then
            If tcpClient.Client.Connected Then
                sendBytes = NetworkPaket.GenerateByteStream(sendBytes)
                Try
                    Dim networkStream As NetworkStream = tcpClient.GetStream()
                    If networkStream.CanWrite Then
                        Dim DataSended As Boolean = False
                        While Not DataSended And NetzConnected()
                            networkStream.Write(sendBytes, 0, sendBytes.Length) 'Sending Data
                            DataSended = True
                        End While
                    End If
                Catch e As Exception
                    Konsole.Write("Sending Error: " + e.ToString)
                End Try
            End If
        End If
    End Sub

    ''' <summary>
    ''' Recieve Data
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub RecieveData()
        Dim StartByte As Byte() = Hauptmenue.Codierung.GetBytes(Net_Orders.Start0000000000000000_.ToString)
        Dim EndByte As Byte() = Hauptmenue.Codierung.GetBytes(Net_Orders._End0000000000000000.ToString)
        While Not CloseConnection And (Not HasConnected Or NetzConnected())
            If Not HasConnected Then
                If NetzConnected() Then
                    HasConnected = True
                End If
            End If
            If tcpClient IsNot Nothing Then
                If tcpClient.Available > 0 And Not tcpClient.NoDelay Then
                    Dim ReadOut As Integer = CInt(tcpClient.Available)
                    If ReadOut > tcpClient.ReceiveBufferSize Then
                        ReadOut = tcpClient.ReceiveBufferSize
                    End If
                    Dim bytes(ReadOut - 1) As Byte 'Output
                    Dim networkStream As NetworkStream = tcpClient.GetStream()
                    If networkStream.CanRead Then
                        Try
                            networkStream.Read(bytes, 0, ReadOut)
                            Data.AddRange(bytes)
                            bytes = Data.ToArray
                            Dim StartCorrect As Boolean = False
                            Dim EndCorrect As Boolean = False
                            While CurrentPos < bytes.Length
                                If Not StartCorrect Then
                                    For I = 0 To StartByte.Length - 1
                                        If I < bytes.Length Then
                                            If bytes(I) <> StartByte(I) Then
                                                StartCorrect = False
                                                Exit For
                                            ElseIf I = StartByte.Length - 1 Then
                                                StartCorrect = True
                                            End If
                                        End If
                                    Next
                                End If
                                If Not EndCorrect Then
                                    For I = 0 To EndByte.Length - 1
                                        If CurrentPos - I >= 0 Then
                                            If bytes(CurrentPos - I) <> EndByte(EndByte.Length - I - 1) Then
                                                EndCorrect = False
                                                Exit For
                                            ElseIf I = EndByte.Length - 1 Then
                                                EndCorrect = True
                                            End If
                                        End If
                                    Next
                                End If
                                If StartCorrect And EndCorrect Then
                                    EndCorrect = False
                                    StartCorrect = False
                                    Dim B(CurrentPos - StartByte.Length - EndByte.Length) As Byte
                                    Array.ConstrainedCopy(bytes, StartByte.Length, B, 0, B.Length)
                                    Data.RemoveRange(0, CurrentPos + 1)
                                    bytes = Data.ToArray
                                    CurrentPos = 0
                                    Dim CurrentData As New NetworkPaket(B)
                                    Select Case CurrentData.ReadString
                                        Case Net_Orders.Close_Connection.ToString
                                            Close() 'We get closed
                                            Exit Sub
                                        Case Else
                                            Hauptmenue.Lobby.NetzBefehlRecieved(CurrentData)
                                    End Select
                                End If
                                CurrentPos += 1
                            End While
                        Catch
                        End Try
                    End If
                Else
                    Threading.Thread.Sleep(ThreadSleepTime)
                End If
            End If
        End While
    End Sub
    Public Function NetzConnected() As Boolean
        If tcpClient IsNot Nothing Then
            If tcpClient.Client IsNot Nothing Then
                Return tcpClient.Client.Connected
            Else
                Return False
            End If
        Else
            Return False
        End If
    End Function
End Class

''' <summary>
''' The Class for the Server.
''' </summary>
''' <remarks></remarks>
Public Class ServerClassLobby
    ''' <summary>
    ''' Host for IP
    ''' </summary>
    ''' <remarks></remarks>
    Dim tcpListenerIP As TcpListener
    ''' <summary>
    ''' TcpClients of the Host.
    ''' </summary>
    ''' <remarks></remarks>
    Dim tcpClients As New List(Of Client)
    ''' <summary>
    ''' Connections that should be closed
    ''' </summary>
    ''' <remarks></remarks>
    Dim ClosingClients As New List(Of Integer)
    Private Class Client
        Public tcpClient As TcpClient
        Public PlayerID As Integer = Integer.MinValue
        ''' <summary>
        ''' Backbuffer for our read in.
        ''' </summary>
        ''' <remarks></remarks>
        Public Data As New List(Of Byte)
        ''' <summary>
        ''' The Current Position of our Reader.
        ''' </summary>
        ''' <remarks></remarks>
        Public CurrentPos As Integer
        ''' <summary>
        ''' Did we send all Gameinfo to this Client?
        ''' </summary>
        ''' <remarks></remarks>
        Public NewlyCreated As Boolean = True
        Public Sub New(ByVal tcpClient As TcpClient, ByVal Clients As List(Of Client))
            Me.tcpClient = tcpClient
            tcpClient.ReceiveBufferSize = NetworkPaket.MaxRecieveBuffer
            While PlayerIDExists(PlayerID, Clients)
                PlayerID += 1
            End While
        End Sub
        Public Function PlayerIDExists(ByVal ID As Integer, ByVal Clients As List(Of Client))
            For Each Client In Clients
                If Client.PlayerID = ID Then
                    Return True
                End If
            Next
            Return False
        End Function
    End Class
    ''' <summary>
    ''' Thread for the Listening
    ''' </summary>
    ''' <remarks></remarks>
    Dim ListenThread As Threading.Thread
    ''' <summary>
    ''' Closing connection
    ''' </summary>
    ''' <remarks></remarks>
    Dim CloseConnection As Boolean = False
    ''' <summary>
    ''' We listen for Data
    ''' </summary>
    ''' <remarks></remarks>
    Dim Listening As Boolean = True
    ''' <summary>
    ''' Are we connected?
    ''' </summary>
    ''' <remarks></remarks>
    Dim Connected As Boolean = False
    ''' <summary>
    ''' Sending Server Pakets.
    ''' </summary>
    ''' <remarks></remarks>
    Dim Sending As Boolean = False
    ''' <summary>
    ''' Pakets reciebied from Clients
    ''' </summary>
    ''' <remarks></remarks>
    Dim Pakets As New List(Of ServerPaket)


    Public Sub LaunchServer(ByVal Port As Integer)
        tcpListenerIP = New TcpListener(System.Net.IPAddress.Any, Port)
        tcpListenerIP.Start() 'Start Connection
        Connected = True
        ListenThread = New Threading.Thread(AddressOf RecieveData)
        ListenThread.Name = "Server Game Listening"
        ListenThread.Start()
    End Sub
    ''' <summary>
    ''' Closes this Client Session.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Close()
        CloseConnection = True
        Connected = False
        If tcpClients IsNot Nothing Then
            SendData(Net_Orders.Close_Connection.ToString)
            For Each Client In tcpClients
                Client.tcpClient.Close()
            Next
            tcpClients.Clear()
        End If
        If tcpListenerIP IsNot Nothing Then
            tcpListenerIP.Stop()
        End If
        If ListenThread IsNot Nothing Then
            ListenThread.Abort()
        End If

    End Sub
    ''' <summary>
    ''' Send Data to or Player
    ''' </summary>
    ''' <param name="Data"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal Data As String)
        SendData(Data, 0, True)
    End Sub
    ''' <summary>
    ''' Send Data to or Player
    ''' </summary>
    ''' <param name="Data"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal Data As String, ByVal PlayerID As Integer, ByVal ToAllPlayer As Boolean, Optional ByVal OnlyToPlayer As Boolean = False)
        If tcpClients IsNot Nothing Then
            If NetzConnected() Then
                WaitForSending()
                Data = NetworkPaket.GenerateStringStream(Data)
                If ToAllPlayer Then
                    For Each Player In tcpClients 'Send it to all other Clients
                        Dim sendBytes As [Byte]() = Hauptmenue.Codierung.GetBytes(Data) 'Convert String into Bytes
                        Try
                            Dim networkStream As NetworkStream = Player.tcpClient.GetStream()
                            If networkStream.CanWrite Then
                                Dim DataSended As Boolean = False
                                While Not DataSended And Player.tcpClient.Client.Connected
                                    networkStream.Write(sendBytes, 0, sendBytes.Length) 'Sending Data
                                    DataSended = True
                                End While
                            End If
                        Catch e As Exception
                            Konsole.Write("Sending Error: " + e.ToString)
                        End Try
                    Next
                ElseIf OnlyToPlayer Then
                    For Each Player In tcpClients 'Send it to all other Clients
                        If Player.PlayerID = PlayerID Then
                            Dim sendBytes As [Byte]() = Hauptmenue.Codierung.GetBytes(Data) 'Convert String into Bytes
                            Try
                                Dim networkStream As NetworkStream = Player.tcpClient.GetStream()
                                If networkStream.CanWrite Then
                                    Dim DataSended As Boolean = False
                                    While Not DataSended And Player.tcpClient.Client.Connected
                                        networkStream.Write(sendBytes, 0, sendBytes.Length) 'Sending Data
                                        DataSended = True
                                    End While
                                End If
                            Catch e As Exception
                                Konsole.Write("Sending Error: " + e.ToString)
                            End Try
                        End If
                    Next
                Else
                    For Each Player In tcpClients 'Send it to all other Clients
                        If Player.PlayerID <> PlayerID Then
                            Dim sendBytes As [Byte]() = Hauptmenue.Codierung.GetBytes(Data) 'Convert String into Bytes
                            Try
                                Dim networkStream As NetworkStream = Player.tcpClient.GetStream()
                                If networkStream.CanWrite Then
                                    Dim DataSended As Boolean = False
                                    While Not DataSended And Player.tcpClient.Client.Connected
                                        networkStream.Write(sendBytes, 0, sendBytes.Length) 'Sending Data
                                        DataSended = True
                                    End While
                                End If
                            Catch e As Exception
                                Konsole.Write("Sending Error: " + e.ToString)
                            End Try
                        End If
                    Next
                End If
                Sending = False
            End If
        End If
    End Sub
    ''' <summary>
    ''' Send Data to or Player
    ''' </summary>
    ''' <param name="Data"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal Data As Byte(), ByVal PlayerID As Integer, ByVal ToAllPlayer As Boolean, ByVal OnlyToPlayer As Boolean)
        If tcpClients IsNot Nothing Then
            If NetzConnected() Then
                WaitForSending()
                Data = NetworkPaket.GenerateByteStream(Data)
                If ToAllPlayer Then
                    For Each Player In tcpClients 'Send it to all other Clients
                        Try
                            Dim networkStream As NetworkStream = Player.tcpClient.GetStream()
                            If networkStream.CanWrite Then
                                Dim DataSended As Boolean = False
                                While Not DataSended And Player.tcpClient.Client.Connected
                                    networkStream.Write(Data, 0, Data.Length) 'Sending Data
                                    DataSended = True
                                End While
                            End If
                        Catch e As Exception
                            Konsole.Write("Sending Error: " + e.ToString)
                        End Try
                    Next
                ElseIf OnlyToPlayer Then
                    For Each Player In tcpClients 'Send it to all other Clients
                        If Player.PlayerID = PlayerID Then
                            Try
                                Dim networkStream As NetworkStream = Player.tcpClient.GetStream()
                                If networkStream.CanWrite Then
                                    Dim DataSended As Boolean = False
                                    While Not DataSended And Player.tcpClient.Client.Connected
                                        networkStream.Write(Data, 0, Data.Length) 'Sending Data
                                        DataSended = True
                                    End While
                                End If
                            Catch e As Exception
                                Konsole.Write("Sending Error: " + e.ToString)
                            End Try
                            Exit For
                        End If
                    Next
                Else
                    For Each Player In tcpClients 'Send it to all other Clients
                        If Player.PlayerID <> PlayerID Then
                            Try
                                Dim networkStream As NetworkStream = Player.tcpClient.GetStream()
                                If networkStream.CanWrite Then
                                    Dim DataSended As Boolean = False
                                    While Not DataSended And Player.tcpClient.Client.Connected
                                        networkStream.Write(Data, 0, Data.Length) 'Sending Data
                                        DataSended = True
                                    End While
                                End If
                            Catch e As Exception
                                Konsole.Write("Sending Error: " + e.ToString)
                            End Try
                        End If
                    Next
                End If
                Sending = False
            End If
        End If
    End Sub
    ''' <summary>
    ''' Send Data to or Player
    ''' </summary>
    ''' <param name="Data"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal Data As Byte())
        SendData(Data, 0, True, False)
    End Sub
    ''' <summary>
    ''' Send Data to or Player
    ''' </summary>
    ''' <param name="Data"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal Data As String, ByVal PlayerID As Integer)
        If tcpClients IsNot Nothing Then
            If NetzConnected() Then
                WaitForSending()
                Data = NetworkPaket.GenerateStringStream(Data)
                For Each Player In tcpClients 'Send it to all other Clients
                    If Player.PlayerID = PlayerID Then
                        Dim sendBytes As [Byte]() = Hauptmenue.Codierung.GetBytes(Data) 'Convert String into Bytes
                        Try
                            Dim networkStream As NetworkStream = Player.tcpClient.GetStream()
                            If networkStream.CanWrite Then
                                Dim DataSended As Boolean = False
                                While Not DataSended And Player.tcpClient.Client.Connected
                                    networkStream.Write(sendBytes, 0, sendBytes.Length) 'Sending Data
                                    DataSended = True
                                End While
                            End If
                        Catch e As Exception
                            Konsole.Write("Sending Error: " + e.ToString)
                        End Try
                        Exit For
                    End If
                Next
                Sending = False
            End If
        End If
    End Sub
    ''' <summary>
    ''' Send Data to or Player
    ''' </summary>
    ''' <param name="Data"></param>
    ''' <remarks></remarks>
    Public Sub SendData(ByVal Data As Byte(), ByVal PlayerID As Integer)
        If tcpClients IsNot Nothing Then
            If NetzConnected() Then
                WaitForSending()
                Data = NetworkPaket.GenerateByteStream(Data)
                For Each Player In tcpClients 'Send it to all other Clients
                    If Player.PlayerID = PlayerID Then
                        Try
                            Dim networkStream As NetworkStream = Player.tcpClient.GetStream()
                            If networkStream.CanWrite Then
                                Dim DataSended As Boolean = False
                                While Not DataSended And Player.tcpClient.Client.Connected
                                    networkStream.Write(Data, 0, Data.Length) 'Sending Data
                                    DataSended = True
                                End While
                            End If
                        Catch e As Exception
                            Konsole.Write("Sending Error: " + e.ToString)
                        End Try
                        Exit For
                    End If
                Next
                Sending = False
            End If
        End If
    End Sub

    Public Sub AddPaket(ByVal Paket As ServerPaket)
        Pakets.Add(Paket)
    End Sub
    ''' <summary>
    ''' Recieve Data
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub RecieveData()
        Dim StartByte As Byte() = Hauptmenue.Codierung.GetBytes(Net_Orders.Start0000000000000000_.ToString)
        Dim EndByte As Byte() = Hauptmenue.Codierung.GetBytes(Net_Orders._End0000000000000000.ToString)
        While Not CloseConnection
            Listening = True
            For I = 0 To ClosingClients.Count - 1
                CloseConnectionToClient(ClosingClients(I))
            Next
            ClosingClients.Clear()
            Dim I3 As Integer = 0
            While I3 < tcpClients.Count
                If Not tcpClients(I3).tcpClient.Client.Connected Then
                    CloseConnectionToClient(tcpClients(I3).PlayerID)
                Else
                    I3 += 1
                End If
            End While
            While tcpListenerIP.Pending  'Somebody wants to connect to us.
                tcpClients.Add(New Client(tcpListenerIP.AcceptTcpClient(), tcpClients))
                Hauptmenue.Lobby.PlayerCreated(tcpClients(tcpClients.Count - 1).PlayerID)
                Pakets.Add(New ServerPaket("PlayerData:" + BaseLobby.Members(BaseLobby.Members.Count - 1).ToString, tcpClients(tcpClients.Count - 1).PlayerID, False, True)) 'Send Player Data only to the specific Client 
                For I = 0 To BaseLobby.Members.Count - 2
                    Pakets.Add(New ServerPaket("PlayerCreated:" + BaseLobby.Members(I).ToString, tcpClients(tcpClients.Count - 1).PlayerID, False, True))
                Next
            End While
            If tcpClients IsNot Nothing Then
                Dim RecievedData As Boolean = False
                For I = 0 To tcpClients.Count - 1
                    If tcpClients(I).tcpClient.Available > 0 And Not tcpClients(I).tcpClient.NoDelay Then
                        RecievedData = True
                        Dim ReadOut As Integer = CInt(tcpClients(I).tcpClient.Available) 'To Avoid Zero Bytes
                        If ReadOut > tcpClients(I).tcpClient.ReceiveBufferSize Then
                            ReadOut = tcpClients(I).tcpClient.ReceiveBufferSize
                        End If
                        Dim bytes(ReadOut - 1) As Byte 'Output
                        Dim networkStream As NetworkStream = tcpClients(I).tcpClient.GetStream()
                        If networkStream.CanRead Then
                            Try
                                networkStream.Read(bytes, 0, CInt(ReadOut))
                                tcpClients(I).Data.AddRange(bytes)
                                bytes = tcpClients(I).Data.ToArray
                                Dim StartCorrect As Boolean = False
                                Dim EndCorrect As Boolean = False
                                While tcpClients(I).CurrentPos < bytes.Length
                                    If Not StartCorrect Then
                                        For I2 = 0 To StartByte.Length - 1
                                            If I2 < bytes.Length Then
                                                If bytes(I2) <> StartByte(I2) Then
                                                    StartCorrect = False
                                                    Exit For
                                                ElseIf I2 = StartByte.Length - 1 Then
                                                    StartCorrect = True
                                                End If
                                            End If
                                        Next
                                    End If
                                    If Not EndCorrect Then
                                        For I2 = 0 To EndByte.Length - 1
                                            If tcpClients(I).CurrentPos - I2 >= 0 Then
                                                If bytes(tcpClients(I).CurrentPos - I2) <> EndByte(EndByte.Length - I2 - 1) Then
                                                    EndCorrect = False
                                                    Exit For
                                                ElseIf I2 = EndByte.Length - 1 Then
                                                    EndCorrect = True
                                                End If
                                            End If
                                        Next
                                    End If
                                    If StartCorrect And EndCorrect Then
                                        EndCorrect = False
                                        StartCorrect = False
                                        Dim B(tcpClients(I).CurrentPos - StartByte.Length - EndByte.Length) As Byte
                                        Array.ConstrainedCopy(bytes, StartByte.Length, B, 0, B.Length)
                                        tcpClients(I).Data.RemoveRange(0, tcpClients(I).CurrentPos + 1)
                                        bytes = tcpClients(I).Data.ToArray
                                        tcpClients(I).CurrentPos = 0
                                        Dim CurrentData As New NetworkPaket(B)
                                        Pakets.Add(New ServerPaket(B, tcpClients(I).PlayerID))
                                        Dim X As String = CurrentData.ReadString
                                        'Use the Data
                                        Select Case CurrentData.ReadString
                                            Case Net_Orders.Close_Connection.ToString
                                                ClosingClients.Add(tcpClients(I).PlayerID)
                                            Case Else
                                                Hauptmenue.Lobby.NetzBefehlRecieved(CurrentData)
                                        End Select
                                    End If
                                    tcpClients(I).CurrentPos += 1
                                End While
                            Catch
                            End Try
                        End If
                    End If
                Next
            End If
            Listening = False
            'Sleep
            Threading.Thread.Sleep(ThreadSleepTime)
            While Sending Or Pakets.Count > 0
                Threading.Thread.Sleep(ThreadSleepTime)
            End While
        End While
    End Sub
    Private Sub CloseConnectionToClient(ByVal ID As Integer)
        Hauptmenue.Lobby.KillPlayer(ID)
        Pakets.Add(New ServerPaket("KillPlayer:" + ID.ToString, ID, True))
        For I = 0 To tcpClients.Count - 1
            If tcpClients(I).PlayerID = ID Then
                tcpClients.RemoveAt(I)
                Exit For
            End If
        Next
    End Sub
    ''' <summary>
    ''' We send all Network Pakets
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub SendPakets()
      WaitForSending
        For Each Paket In Pakets
            SendData(Paket.Bytes, Paket.PlayerID, Paket.All_Player, Paket.Only_To_Player)
        Next
        Pakets.Clear()
        Sending = False
    End Sub
    ''' <summary>
    ''' Are we connected
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function NetzConnected() As Boolean
        Return Connected
    End Function
    Private Sub WaitForSending()
        Sending = True
        While Listening
            Threading.Thread.Sleep(ThreadSleepTime)
        End While
    End Sub
End Class
